// [LICENCE-HEADER]
//
package org.libermundi.theorcs.core.util;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

/**
 * An implement of PaginatedList
 *
 */
public class PaginatedListImpl<E> implements PaginatedList<E> {
    private List<E> _pageList;
    private int _totalItems;
    private int _pageIndex;
    private int _pageSize;

    public PaginatedListImpl() {
        this(new ArrayList<E>(), 0, 0, 0);
    }

    public PaginatedListImpl(int totalItems, int pageIndex, int pageSize) {
        this(new ArrayList<E>(), totalItems, pageIndex, pageSize);
    }

    public PaginatedListImpl(List<E> pageList, int totalItems, int pageIndex, int pageSize) {
        _pageList = pageList;
        _totalItems = totalItems;

        _pageIndex = pageIndex;
        _pageSize = pageSize;
        validParams();
    }
    
    /*
     * @see org.libermundi.theorcs.core.util.PaginatedList#getPageIndex()
     */
    @Override
    public int getPageIndex() {
        return _pageIndex;
    }
    
    /*
     * @see org.libermundi.theorcs.core.util.PaginatedList#getPageSize()
     */
    @Override
    public int getPageSize() {
        return _pageSize;
    }
    
    /*
     * @see org.libermundi.theorcs.core.util.PaginatedList#getActualPageSize()
     */
    @Override
    public int getActualPageSize() {
        return _pageList.size();
    }
    
    /*
     * @see org.libermundi.theorcs.core.util.PaginatedList#isFirstPage()
     */
    @Override
    public boolean isFirstPage() {
        return (_pageIndex == 0);
    }
    
    /*
     * @see org.libermundi.theorcs.core.util.PaginatedList#isLastPage()
     */
    @Override
    public boolean isLastPage() {
        return (_pageIndex == getTotalPages() - 1);
    }
    
    /*
     * @see org.libermundi.theorcs.core.util.PaginatedList#isNextPageAvailable()
     */
    @Override
    public boolean isNextPageAvailable() {
        return !isLastPage();
    }
    
    /*
     * @see org.libermundi.theorcs.core.util.PaginatedList#isPreviousPageAvailable()
     */
    @Override
    public boolean isPreviousPageAvailable() {
        return !isFirstPage();
    }
    
    /*
     * @see org.libermundi.theorcs.core.util.PaginatedList#getTotalPages()
     */
    @Override
    public int getTotalPages() {
        int remainder = (_totalItems % _pageSize == 0) ? 0 : 1;
        return (_totalItems / _pageSize) + remainder;
    }
    
    /*
     * @see org.libermundi.theorcs.core.util.PaginatedList#getTotalItems()
     */
    @Override
    public int getTotalItems() {
        return _totalItems;
    }
    
    /*
     * @see org.libermundi.theorcs.core.util.PaginatedList#setTotalItems(int)
     */
    @Override
    public void setTotalItems(int totalItems) {
        _totalItems = totalItems;
    }
    
    /*
     * @see org.libermundi.theorcs.core.util.PaginatedList#getPageList()
     */
    @Override
    public List<E> getPageList() {
        return Collections.unmodifiableList(_pageList);
    }
    
    /*
     * @see org.libermundi.theorcs.core.util.PaginatedList#setPageList(java.util.List)
     */
    @Override
    public void setPageList(List<E> pageList) {
        _pageList = pageList;
    }
    
    /*
     * @see org.libermundi.theorcs.core.util.PaginatedList#toArray()
     */
    @Override
    public E[] toArray(E[] arr) {
        return _pageList.toArray(arr);
    }
    
    /*
     * @see java.lang.Iterable#iterator()
     */
    @Override
    public Iterator<E> iterator() {
        return _pageList.iterator();
    }
    
    /*
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        return _pageList.toString();
    }
    
    private void validParams() {
        if (_pageSize <= 0) {
            _pageSize = 1;
        }

        if (_pageIndex < 0) {
            _pageIndex = 0;
        } else if (_pageIndex >= getTotalPages()) {
            _pageIndex = getTotalPages() - 1;
        }
    }
}